package com.phospherus.user.service

import com.phospherus.common.MD5Util
import com.phospherus.common.service.impl.BaseServiceImpl
import com.phospherus.user.entity.Resource
import com.phospherus.user.entity.RoleUser
import com.phospherus.user.entity.User
import com.phospherus.user.repository.UserRepository
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.stereotype.Service
import javax.transaction.Transactional

/**
 * @author songjinlong
 * @version 1.0
 * @since 2017/11/8
 */
@Service
@Transactional
class UserService : BaseServiceImpl<User, Long, UserRepository>() {
    @Autowired
    lateinit var resourceService: ResourceService
    @Autowired
    lateinit var roleUserService: RoleUserService
    @Autowired
    lateinit var orgService: OrgService
    @Autowired
    lateinit var roleService: RoleService
    fun login(account: String, passWord: String): LoginResultHandler? {
        val passW = MD5Util.getMD5(passWord)
        val user: User = repository.findByAccountAndPassWord(account, passW) ?: return null
        val resources = resourceService.getResources(user) ?: null
        return LoginResultHandler(user, resources)
    }

    fun createUser(user: User, roleIds: List<String>?): CreateUserHandler {
        //FIXME 需求有可能变更为一个用户属于多个部门
        val passW = MD5Util.token(user.account).substring(0, 6)
        var org = if (user.orgId != null && user.orgId!! > 0) {
            orgService.findOne(user.orgId)
        } else {
            null
        }
        var user = save(user.apply {
            this.passWord = MD5Util.getMD5(passW)
            this.orgId = org?.id
            this.orgName = org?.orgName
            })
        var roleUsers = roleIds?.mapTo(ArrayList(), { RoleUser(roleId = it.toLong(), roleName = roleService.getRoleNameByRoleId(it.toLong()), userId = user.id, userName = user.userName, account = user.account) })
        roleUserService.save(roleUsers)
        return CreateUserHandler(user, passW)
    }

    fun modifyUserInfo(userId: Long, email: String, phone: String): Boolean {
        return try {
            repository.modifyUserInfo(userId, email, phone)
            true
        } catch (e: Exception) {
            false
        }
    }

    fun resetPassWord(userId: Long): String {
        val passW = MD5Util.token(userId.toString()).substring(0, 6)
        repository.modifyPassWord(userId, MD5Util.getMD5(passW))
        return passW
    }

    fun modifyPassWord(oldPassWord: String, newPassWord: String, user: User): Boolean {
        val tUser = findOne(user.id)
        if (tUser.passWord == MD5Util.getMD5(oldPassWord)) {
            user.passWord = MD5Util.getMD5(newPassWord)
            repository.modifyPassWord(user.id, user.passWord)
            return true
        }
        return false
    }

    fun getBindingsUsers(roleId: Long): List<User> {
        return repository.getBindingsUsers(roleId)
    }

    fun getUnBindingsUsers(roleId: Long): List<User> {
        return repository.getUnBindingsUsers(roleId)
    }

    /**
     * roleId:角色ID
     * createUserId:流程发起者ID
     */
    fun getNextUserByRoleIdAndCurrUser(roleId: Long, createUserId: Long?, user: User): User {
        var users = getUsersByRoleId(roleId)
        var createUser = findOne(createUserId)
        if (roleId == 2L) {
            var u = users.find { it.orgId == createUser.orgId }
            if (u != null) {
                return u
            }
        }
        return if (users.size > 1) {
            if (createUserId == null) {
                return users[0]
            }
            var cUser = users.find { it.id == createUser.id }
            if (cUser != null) {
                cUser
            } else {
                var sameOrgUsers = users.filter { it.orgId == user.orgId }
                if (sameOrgUsers?.isNotEmpty()) {
                    sameOrgUsers[0]
                } else {
                    users[0]
                }
            }
        } else {
            users[0]
        }
    }

    fun getUsersByRoleId(roleId: Long): List<User> = repository.getUsersByRoleId(roleId)
    fun modifyUser(userId: Long, orgId: Long, leader: Boolean, roleIds: List<String>) {
        var org = orgService.findOne(orgId)
        var user = findOne(userId)
        save(user.apply {
            this.isLeader = leader
            this.orgId = org.id
            this.orgName = org.orgName
        })
        roleUserService.deleteByUserId(userId)
        var roleUsers = roleIds?.mapTo(ArrayList(), { RoleUser(roleId = it.toLong(), roleName = roleService.getRoleNameByRoleId(it.toLong()), userId = user.id, userName = user.userName, account = user.account) })
        roleUserService.save(roleUsers)
    }
}

data class CreateUserHandler(
        var user: User,
        var passWord: String
)

data class LoginResultHandler(
        var user: User?,
        var resources: List<Resource>?
)